package bosque.unc.simulador;

import java.util.HashMap;
import java.util.Observable;

import bosque.unc.Funciones;
import bosque.unc.enumerations.EncoderNombre;
import bosque.unc.enumerations.Angulo;
import bosque.unc.enumerations.Notificacion;

public class EncoderSimulator extends Observable
{
	private Integer angulo = 0;   // angulo en segundos
	private Integer segundos = 0;
	private Integer minutos = 0;
	private Integer grados = 0;
	private Integer signo = 1;
	private Boolean cambio = false;
	private EncoderNombre nombre;
	
	public EncoderSimulator(EncoderNombre nom)
	{
		this.nombre = nom;
	}
	
	/**
	 * Calcula en angulo que muestran los encoders en segundos sexagesimales y lo setea en la variable
	 * angulo de la clase
	 * @param grad
	 * @param min
	 * @param seg
	 * @return
	 */
	public void calcularAnguloEnSegundos(Integer grad, Integer min, Integer seg, Integer signo)
	{		
		this.angulo = Funciones.gradMinSegToSegundosSex(grad, min, seg, signo);
					
	}
	
	/**
	 * Calcula en angulo que muestran los encoders en segundos sexagesimales y lo setea en la variable
	 * angulo de la clase
	 *
	 */
	public void calcularAnguloEnSegundosThis()
	{		
		this.angulo = Funciones.gradMinSegToSegundosSex(Math.abs(this.grados), this.minutos, this.segundos, this.signo);
					
	}
	
	
	
	public void actualizarEncoderAlfa(Angulo ang)
	{
		switch(ang)
		{
		case GRADOS:
			notifyObservers(Notificacion.SIMU_ENCODER_ALFA_GRADOS);
			break;
		case MINUTOS:
			notifyObservers(Notificacion.SIMU_ENCODER_ALFA_MINUTOS);
			break;
		case SEGUNDOS:
			notifyObservers(Notificacion.SIMU_ENCODER_ALFA_SEGUNDOS);
			break;
		default:
			notifyObservers(Notificacion.SIMU_ENCODER_ALFA_SIGNO);
			break;
		
		}
		
		
	}
	
	public void actualizarEncoderDelta(Angulo ang)
	{
		switch(ang)
		{
		case GRADOS:
			notifyObservers(Notificacion.SIMU_ENCODER_DELTA_GRADOS);
			break;
		case MINUTOS:
			notifyObservers(Notificacion.SIMU_ENCODER_DELTA_MINUTOS);
			break;
		case SEGUNDOS:
			notifyObservers(Notificacion.SIMU_ENCODER_DELTA_SEGUNDOS);
			break;
		default:
			notifyObservers(Notificacion.SIMU_ENCODER_DELTA_SIGNO);
			break;
		
		}
		
		
	}
	
	public void calcularGradMinSeg()
	{
		this.signo = (this.angulo <0) ? -1 : 1;
		HashMap<Angulo, Integer> anguloGMS = new HashMap<Angulo, Integer>();
		Double gradosSex = Funciones.segundosToGradosSex(this.angulo);
		anguloGMS = Funciones.radToGradMinSeg(Math.toRadians(gradosSex));
		this.grados = Math.abs(anguloGMS.get(Angulo.GRADOS));
		this.minutos = anguloGMS.get(Angulo.MINUTOS);
		this.segundos = anguloGMS.get(Angulo.SEGUNDOS);
		//System.out.println(signo + " " + grados + " " + minutos + " " + segundos);
		setChanged();
		if(this.nombre.equals(EncoderNombre.ALFA))
		{			
			notifyObservers(Notificacion.SIMU_ENCODER_ALFA);
		}
		else
		{
			notifyObservers(Notificacion.SIMU_ENCODER_DELTA);
		}
	}
	
	public void incrementar(Sentido sentido, Integer p)
	{
		//System.out.println(this.angulo);
		
		Integer paso = p;
		
		
		
		//this.angulo = anguloTemp;
		//paso = (this.angulo < 0 ) ? (p * (-1)) : p;
		if(sentido.equals(Sentido.HORARIO))
		{
			/*Integer anguloTemp = this.angulo + paso;
			if(anguloTemp >(180 * 3600) )
			{
				anguloTemp = (anguloTemp - (180 * 3600)) * (-1);
				this.angulo = anguloTemp;
				
			}
			else if(anguloTemp < (-180 * 3600) )
			{
				anguloTemp = (-anguloTemp - (180 * 3600)) ;
				this.angulo = anguloTemp;
			}
			else
			{
				
			}
			
			paso = (this.angulo < 0 ) ? (paso * (-1)) : paso;*/
			this.angulo = angulo + paso;
		}		
		
		
		else
		{	
			/*if(this.angulo >=0)
			{
				Integer anguloTemp = this.angulo - paso;
				//System.out.println(anguloTemp);
				if(anguloTemp < 0 )
				{
					anguloTemp = ((180 * 3600) + anguloTemp) * (-1);
					this.angulo = anguloTemp;
					
				}
				
				else
				{
					
				}
			}
			else
			{
				Integer anguloTemp = this.angulo + paso;
				if(anguloTemp > 0 )
				{
					anguloTemp = (-anguloTemp - (180 * 3600)) ;
					this.angulo = anguloTemp;
				}
				else
				{
					
				}
			}*/
			
			
			
			
			//paso = (this.angulo < 0 ) ? (paso * (-1)) : paso;
			this.angulo = angulo - paso;
			//System.out.println(this.angulo + " " + paso);
		}
	}
	
	/*public void incrementar(Sentido sentido)
	{
		Integer segTemp = this.segundos;
		Integer minTemp = this.minutos;
		Integer gradTemp = this.grados;
		Integer sumando = 30;
		
		switch(sentido)
		{
		case HORARIO: sumando = 1;
			break;
		case ANTIHORARIO: sumando = -1;
			break;
		}
		
				
		segTemp = segTemp + (sumando * signo);
		if(this.grados.equals(180) && this.minutos.equals(0) && segTemp.equals(1) && this.signo.equals(1))
		{
			this.signo = -1;
			this.grados = 179;
			this.minutos = 59;
			this.segundos = 59;
			
		}
		else if(this.grados.equals(0) && this.minutos.equals(0) && segTemp.equals(0) && this.signo.equals(-1))
		{
			this.signo = 1;
			this.grados = 0;
			this.minutos = 0;
			this.segundos = 0;
			
		}
		
		else if(this.grados.equals(0) && this.minutos.equals(0) && segTemp.equals(-1) && this.signo.equals(1) && sentido.equals(Sentido.ANTIHORARIO))
		{
			this.signo = -1;
			this.grados = 0;
			this.minutos = 0;
			this.segundos = 1;
			
		}
		
//		else if(this.grados.equals(180) && this.minutos.equals(0) && segTemp.equals(60) && this.signo.equals(-1) && sentido.equals(Sentido.ANTIHORARIO))
//		{
//			this.signo = 1;
//			this.grados = 180;
//			this.minutos = 0;
//			this.segundos = 0;
//			
//		}
		
		else
		{
			if(segTemp.equals(60) )
			{
				this.segundos = 0;
				minTemp = minTemp + (sumando * signo);
				if(minTemp.equals(60))
				{
					this.minutos = 0;
					this.grados = this.grados + (sumando * signo);
					if(this.grados.equals(180) && sentido.equals(Sentido.ANTIHORARIO) && this.signo.equals(-1))
					{
						this.signo = 1;
					}
					
				}
				else
				{
					this.minutos = minTemp;
				}
			}
			else if(segTemp.equals(-1))
			{
				this.segundos = 59;
				minTemp = minTemp + (sumando * signo);
				if(minTemp.equals(-1))
				{
					this.minutos = 59;
					this.grados = this.grados + (sumando * signo);
//					if(this.grados.equals(180) && sentido.equals(Sentido.ANTIHORARIO) && this.signo.equals(-1))
//					{
//						this.signo = 1;
//					}
					
				}
				else
				{
					this.minutos = minTemp;
				}
				
				
			}
			else
			{
				this.segundos = segTemp;
			}
		}
		
		
	}*/

	public Integer getSegundos()
	{
		return segundos;
	}

	public void setSegundos(Integer segundos)
	{
		this.segundos = segundos;
		setChanged();
		notifyObservers((nombre.equals(EncoderNombre.DELTA) ? Notificacion.SIMU_ENCODER_DELTA_SEGUNDOS : Notificacion.SIMU_ENCODER_ALFA_SEGUNDOS));
	}

	public Integer getMinutos()
	{
		return minutos;
	}

	public void setMinutos(Integer minutos)
	{
		this.minutos = minutos;
		setChanged();
		notifyObservers((nombre.equals(EncoderNombre.DELTA) ? Notificacion.SIMU_ENCODER_DELTA_MINUTOS : Notificacion.SIMU_ENCODER_ALFA_MINUTOS));
	}

	public Integer getGrados()
	{
		return grados;
	}

	public void setGrados(Integer grados)
	{
		this.grados = grados;
		setChanged();
		notifyObservers((nombre.equals(EncoderNombre.DELTA) ? Notificacion.SIMU_ENCODER_DELTA_GRADOS : Notificacion.SIMU_ENCODER_ALFA_GRADOS));
	}

	public Integer getSigno()
	{
		return signo;
		
	}

	public void setSigno(Integer signo)
	{
		this.signo = signo;
		setChanged();
		notifyObservers((nombre.equals(EncoderNombre.DELTA) ? Notificacion.SIMU_ENCODER_DELTA_SIGNO : Notificacion.SIMU_ENCODER_ALFA_SIGNO));
	}

	public Integer getAngulo() {
		return angulo;
	}

	public void setAngulo(Integer angulo) {
		this.angulo = angulo;
	}
	
	
	
	
}
